package com.yc.cloud.admin.controller;

import com.yc.cloud.admin.dto.mediakit.MediaKitOnRecordMp4Hook;
import com.yc.cloud.admin.dto.mediakit.MediaKitOnPublishHook;
import com.yc.cloud.admin.dto.mediakit.MediaKitOnPublishResponse;
import com.yc.cloud.admin.service.MediaKitApiService;
import com.yc.cloud.admin.service.VideoRecordProcessService;
import com.yc.cloud.admin.service.PublishAuthService;
import com.yc.cloud.admin.service.SnapshotService;

import com.yc.cloud.common.basic.api.ResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource;

import com.yc.cloud.admin.dto.request.MediaKitRecordReqDTO;
import com.yc.cloud.admin.dto.request.MediaKitSnapReqDTO;
import com.yc.cloud.admin.config.MediaKitProperties;
import com.yc.cloud.admin.vo.MediaStreamVo;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/mediakit")
@Api(tags = "流媒体接口")
@Slf4j
public class MediaKitController {

    @Resource
    private MediaKitApiService mediaKitApiService;

    @Resource
    private MediaKitProperties mediaKitProperties;

    @Resource
    private VideoRecordProcessService videoRecordProcessService;

    @Resource
    private PublishAuthService publishAuthService;

    @Resource
    private SnapshotService snapshotService;

    // -------------------- HOOK --------------------
    @ApiOperation("推流鉴权事件回调 on_publish")
    @PostMapping("/hook/on_publish")
    public MediaKitOnPublishResponse onPublish(@Validated @RequestBody MediaKitOnPublishHook payload) {
        log.info("ZLM on_publish: app={}, stream={}, ip={}, schema={}", 
                payload.getApp(), payload.getStream(), payload.getIp(), payload.getSchema());
        
        try {
            // 处理推流鉴权
            MediaKitOnPublishResponse response = publishAuthService.processPublishAuth(payload);
            
            if (response.getCode() == 0) {
                log.info("Publish allowed for stream: {}", payload.getStream());
            } else {
                log.warn("Publish denied for stream: {}, reason: {}", 
                        payload.getStream(), response.getStreamReplace());
            }
            
            return response;
        } catch (Exception e) {
            log.error("Error processing publish auth: stream={}", payload.getStream(), e);
            return MediaKitOnPublishResponse.deny("系统错误，请稍后重试");
        }
    }

    @ApiOperation("录制mp4切片完成事件回调 on_record_mp4")
    @PostMapping("/hook/on_record_mp4")
    public ResponseResult<Boolean> onRecordMp4(@Validated @RequestBody MediaKitOnRecordMp4Hook payload) {
        log.info("ZLM on_record_mp4: {}", payload);
        
        try {
            //设置结束时间为当前系统时间
            payload.setEndTime(LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
            // 处理录像完成事件
            boolean success = videoRecordProcessService.processVideoRecord(payload);
            if (success) {
                log.info("Successfully processed video record for stream: {}", payload.getStream());
                return ResponseResult.success(Boolean.TRUE);
            } else {
                log.error("Failed to process video record for stream: {}", payload.getStream());
                return ResponseResult.failed("Failed to process video record");
            }
        } catch (Exception e) {
            log.error("Error processing video record: stream={}", payload.getStream(), e);
            return ResponseResult.failed("Error processing video record: " + e.getMessage());
        }
    }

    // -------------------- 录制控制 --------------------
    @ApiOperation("开启录制")
    @PostMapping("/record/start")
    public ResponseResult<Boolean> start(@Validated @RequestBody MediaKitRecordReqDTO req) {
        log.info("开始录制请求参数: stream={}", req.getStream());
        boolean ok = mediaKitApiService.startRecord(req);
        return ok ? ResponseResult.success(Boolean.TRUE) : ResponseResult.failed("start record failed");
    }

    @ApiOperation("停止录制")
    @PostMapping("/record/stop")
    public ResponseResult<Boolean> stop(@Validated @RequestBody MediaKitRecordReqDTO req) {
        log.info("停止录制请求参数: stream={}", req.getStream());
        boolean ok = mediaKitApiService.stopRecord(req);
        return ok ? ResponseResult.success(Boolean.TRUE) : ResponseResult.failed("stop record failed");
    }

    @ApiOperation("查询流的录制状态")
    @PostMapping("/record/status")
    public ResponseResult<Boolean> getRecordStatus(@Validated @RequestBody MediaKitRecordReqDTO req) {
        log.info("查询录制状态请求参数: stream={}", req.getStream());
        boolean isRecording = mediaKitApiService.isRecord(req);
        return ResponseResult.success(isRecording);
    }

    // -------------------- 流管理 --------------------
    @ApiOperation("获取所有在线视频流列表")
    @GetMapping("/streams")
    public ResponseResult<List<MediaStreamVo>> getMediaList() {
        try {
            List<MediaStreamVo> streamList = mediaKitApiService.getMediaList();
            
            if (streamList != null) {
                log.info("Successfully retrieved {} media streams", streamList.size());
                return ResponseResult.success(streamList);
            } else {
                log.warn("No media streams found or service returned null");
                return ResponseResult.failed("获取流列表失败: 服务器无响应");
            }
        } catch (Exception e) {
            log.error("Failed to get media list in controller", e);
            return ResponseResult.failed("获取流列表失败: " + e.getMessage());
        }
    }

    
    @PostMapping("/snap")
    @Operation(summary = "获取截图", description = "支持 MediaKit API 和 FFmpeg 两种截图方式")
    public ResponseResult<String> getSnap(@Validated @RequestBody MediaKitSnapReqDTO reqDTO) {
        try {
            String result = snapshotService.captureSnapshot(reqDTO.getUrl(), reqDTO.getSnapMethod());
            
            if (result != null) {
                return ResponseResult.success(result);
            } else {
                return ResponseResult.failed("获取截图失败");
            }
        } catch (Exception e) {
            log.error("获取截图异常", e);
            return ResponseResult.failed("获取截图失败: " + e.getMessage());
        }
    }

    // -------------------- 服务器配置 --------------------
    @ApiOperation("获取服务器配置")
    @GetMapping("/index/api/getServerConfig")
    public ResponseResult<Map<String, Object>> getServerConfig(
            @RequestParam(value = "secret", required = false) String secret) {
        try {
            Map<String, Object> config = mediaKitApiService.getServerConfig(secret);
            
            if (config != null) {
                log.info("Successfully retrieved server config");
                return ResponseResult.success(config);
            } else {
                log.warn("Failed to retrieve server config or config is empty");
                return ResponseResult.failed("获取服务器配置失败: 服务器无响应");
            }
        } catch (Exception e) {
            log.error("Failed to get server config in controller", e);
            return ResponseResult.failed("获取服务器配置失败: " + e.getMessage());
        }
    }

    @ApiOperation("设置服务器配置")
    @PostMapping("/index/api/setServerConfig")
    public ResponseResult<Map<String, Object>> setServerConfig(
            @RequestParam(value = "secret", required = false) String secret,
            @RequestBody Map<String, String> configs) {
        try {
            log.info("Setting server config with {} parameters", configs.size());
            
            Map<String, Object> result = mediaKitApiService.setServerConfig(secret, configs);
            
            if (result != null) {
                log.info("Successfully set server config");
                return ResponseResult.success(result);
            } else {
                log.warn("Failed to set server config or result is empty");
                return ResponseResult.failed("设置服务器配置失败: 服务器无响应");
            }
        } catch (Exception e) {
            log.error("Failed to set server config in controller", e);
            return ResponseResult.failed("设置服务器配置失败: " + e.getMessage());
        }
    }
}


